import uuid

from django.contrib.postgres.fields import ArrayField
from django.db import models
from pgcrypto import fields
from apps.users.models import User
from .types import (
    EMPLOYMENT_STATUS,
    PREFERRED_LANGUAGE_CHOICES,
    RELATIONSHIP_STATUS,
    CLIENT_STATUS_CHOICES,
    RACE_CHOICES,
    GENDER_CHOICES,
    GenderChoices,
    RaceChoices,
    ClientStatusChoices,
    RelationshipStatus,
    EmploymentStatus,
    PreferredLanguageChoices,
    CLIENT_GUARDIAN_CHOICE,
    ClientLegalGuardian,
    InsuranceTypes,
    INSUARANCE_TYPE_CHOICE,
    InsurancePayer,
    INSURANCE_PAYER_CHOICE,
    ClientBillingType,
    CLIENT_BILLING_TYPE,
    MessagingStatusChoices, MESSAGING_STATUS_CHOICES, CLIENT_TYPE, ClientType, PrimaryInsured, PRIMARY_INSURED_CHOICE
)
from localflavor.us.models import USZipCodeField, USStateField

from ..tenant.models import ProviderServices


# Create your models here.

class Client(User):
    user_provider = models.UUIDField(default=uuid.uuid4)
    stripe_account_id = models.CharField(max_length=50, null=True, blank=True)

    suffix = fields.CharPGPSymmetricKeyField(
        max_length=10, null=True, blank=True)
    preferred_name = fields.CharPGPSymmetricKeyField(
        blank=True, null=True, max_length=150)
    is_minor = models.BooleanField(default=False)
    referred_by = fields.CharPGPSymmetricKeyField(null=True, blank=True, max_length=255)
    client_type = models.IntegerField(choices=CLIENT_TYPE,
                                      default=ClientType.INDIVIDUAL.value)
    relationship_status = fields.CharPGPSymmetricKeyField(
        choices=RELATIONSHIP_STATUS,
        default=RelationshipStatus.MARRIED.value,
        max_length=1)
    employment_status = fields.CharPGPSymmetricKeyField(
        choices=EMPLOYMENT_STATUS,
        default=EmploymentStatus.FULL_TIME.value,
        max_length=1)
    status = fields.CharPGPSymmetricKeyField(
        choices=CLIENT_STATUS_CHOICES,
        default=ClientStatusChoices.PENDING.value,
        max_length=1)

    messaging = models.IntegerField(choices=MESSAGING_STATUS_CHOICES,
                                    default=MessagingStatusChoices.ACTIVE.value,
                                    )
    race = fields.CharPGPSymmetricKeyField(
        choices=RACE_CHOICES,
        default=RaceChoices.UNSPECIFIED.value,
        max_length=3)
    races = ArrayField(models.IntegerField(), blank=True, null=True)
    credit_card = fields.CharPGPSymmetricKeyField(null=True, max_length=255)
    ethnicity = fields.CharPGPSymmetricKeyField(
        null=True, blank=True, max_length=255, default='')
    preferred_language = fields.CharPGPSymmetricKeyField(
        choices=PREFERRED_LANGUAGE_CHOICES,
        default=PreferredLanguageChoices.ENGLISH.value,
        max_length=5)
    signed_document = fields.CharPGPSymmetricKeyField(
        null=True, blank=True, max_length=10)
    gender = fields.CharPGPSymmetricKeyField(
        choices=GENDER_CHOICES,
        default=GenderChoices.UNKNOWN.value,
        max_length=3)
    gender_identity = fields.CharPGPSymmetricKeyField(null=True, blank=True, max_length=255)
    billing_type = fields.CharPGPSymmetricKeyField(
        choices=CLIENT_BILLING_TYPE,
        default=ClientBillingType.SELF_PAY.value,
        max_length=3
    )
    note = fields.TextPGPSymmetricKeyField(blank=True)
    first_seen_at = models.DateTimeField(null=True)
    additional_comments = fields.CharPGPSymmetricKeyField(blank=True, null=True, max_length=500)
    date_started = fields.DateTimePGPSymmetricKeyField(auto_now_add=True, null=True, blank=True)
    appointment_email_reminder = models.BooleanField(default=False)
    billing_email_reminder = models.BooleanField(default=False)
    document_get_started = models.BooleanField(default=False)

    class Meta:
        db_table = 'clients'


class ClientAddress(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE,
                               related_name='client_address', null=True)
    address = fields.CharPGPSymmetricKeyField(
        null=True, blank=True, max_length=255)
    state = USStateField(null=True, blank=True)
    city = models.CharField(max_length=50, null=True, blank=True)
    zipcode = USZipCodeField(null=True, blank=True)

    class Meta:
        db_table = 'clients_address'


class ClientGuardian(User):
    user_guardian = models.ForeignKey(Client, on_delete=models.CASCADE,
                                      related_name='client_guardian',
                                      null=True)
    status = fields.CharPGPSymmetricKeyField(
        choices=CLIENT_GUARDIAN_CHOICE,
        default=ClientLegalGuardian.LEGAL_GUARDIAN.value,
        max_length=1)

    class Meta:
        db_table = 'clients_guardian'


class ClientGuardianAddress(models.Model):
    guardian = models.ForeignKey(ClientGuardian, on_delete=models.CASCADE,
                                 null=True, related_name='guardian_addresses')
    address = fields.CharPGPSymmetricKeyField(
        null=True, blank=True, max_length=255)
    state = USStateField(null=True, blank=True)
    city = models.CharField(max_length=50, null=True, blank=True)
    zipcode = USZipCodeField(null=True, blank=True)

    class Meta:
        db_table = 'clients_guardian_address'


def upload_client_insurance_card(instance, filename):
    path = "clientinsurance/{client_id}/{filename}".format(
        client_id=instance.client_id, filename=filename)
    return path


class ClientInsurance(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE,
                               related_name='client_insurance', null=True)
    insurance_type = fields.CharPGPSymmetricKeyField(choices=INSUARANCE_TYPE_CHOICE,
                                                     default=InsuranceTypes.PRIMARY.value,
                                                     max_length=1)
    primary_insured = fields.CharPGPSymmetricKeyField(choices=PRIMARY_INSURED_CHOICE,
                                                      default=PrimaryInsured.CLIENT.value,
                                                      max_length=1)
    insurance_payer = fields.CharPGPSymmetricKeyField(choices=INSURANCE_PAYER_CHOICE,
                                                      default=InsurancePayer.CIGNA_62308.value,
                                                      max_length=1)
    member_id = fields.CharPGPSymmetricKeyField(blank=True, null=True, max_length=150)
    plan_id = fields.CharPGPSymmetricKeyField(blank=True, null=True, max_length=150)
    group_id = fields.CharPGPSymmetricKeyField(blank=True, null=True, max_length=150)
    coinsurance = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    deductible = models.DecimalField(max_digits=10, decimal_places=2, default=0)

    payer_phone_number = fields.CharPGPSymmetricKeyField(
        null=True, blank=True, max_length=15)
    payer_fax = fields.CharPGPSymmetricKeyField(
        null=True, blank=True, max_length=50)
    employer = fields.CharPGPSymmetricKeyField(
        null=True, blank=True, max_length=50)
    card = models.CharField(max_length=500, blank=True, null=True)

    class Meta:
        db_table = 'clients_insurance'


class ClientAuthorizationTracking(models.Model):
    client = models.ForeignKey(Client,
                               on_delete=models.CASCADE,
                               null=True,
                               related_name='client_authorization')
    authorization_number = fields.CharPGPSymmetricKeyField(blank=True,
                                                           null=True,
                                                           max_length=250)
    validity = fields.DateTimePGPSymmetricKeyField(null=True)
    number_of_uses = fields.CharPGPSymmetricKeyField(null=True, blank=True, max_length=250)
    is_active = models.BooleanField(default=False)
    reminding_before_expire = models.BooleanField(default=False)

    class Meta:
        db_table = 'client_authorization_tracking'


class ClientServices(models.Model):
    client = models.ForeignKey(Client,
                               on_delete=models.CASCADE,
                               null=True,
                               related_name='client_service')
    service = models.ForeignKey(ProviderServices,
                                on_delete=models.CASCADE,
                                null=True,
                                )
    fees = models.DecimalField(decimal_places=2, max_digits=10, default=0)
    is_default = models.BooleanField(default=False)

    class Meta:
        db_table = 'client_services'